#include "iproute/buffer.h"
#include "include/unet_def.h"

DEFINE_int32(buf_size, 8192, "buffer size");

namespace unet {

Buffer::Buffer() {
  size_t size = align_size(FLAGS_buf_size);
  mem_ = ::malloc(size);
  CHECK_NOTNULL(mem_);
  end_ = mem_ + size;
  rpos_ = wpos_ = mem_;
}

Buffer::~Buffer() {
  ::free(mem_);
}

void Buffer::EnSureLeftSize(uint32 size) {
  if (WriteableSize() >= size) {
    return;
  }

  uint32 rn = rpos_ - mem_;
  uint32 wn = wpos_ - mem_;
  uint32 new_size = BufferSize();
  while (new_size < size + BufferSize()) {
    new_size += 512;
  }
  mem_ = ::realloc(mem_, new_size);
  CHECK_NOTNULL(mem_);
  end_ = mem_ + new_size;

  rpos_ = mem_ + rn;
  wpos_ = mem_ + wn;
}

char* Buffer::Read(uint32 size) {
  size = align_size(size);
  CHECK(ReadableSize() >= size);

  char* tmp = rpos_;
  rpos_ += size;
  return tmp;
}

void Buffer::Write(const char* buf, uint32 size) {
  EnSureLeftSize(align_size(size));
  ::memcpy(wpos_, buf, size);
  wpos_ += size;

  uint32 padding_size = align_size(size) - size;
  if (padding_size != 0) {
    ::memset(wpos_, 0, padding_size);
    wpos_ += padding_size;
  }
}

}
